<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>HTML5 Canvas 逐帧动画的实现</title>
<style type="text/css">
#canvas{border: 1px solid #ccc;}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="400">
   <p>Your browser does not support the canvas element!</p>
</canvas>
<script type="text/javascript">
Array.prototype.remove = function(obj) {
   for (i in this) {
      if (this[i] === obj) {
         this.splice(i, 1);
      }
   }
}


function Spirit(image, x, y, order) {
   this.image = image;
   this.x = x;
   this.y = y;
   this.order = isNaN(order) ? 0 : order;
   
   this.addTo = function(spirits) { 
      spirits.push(this);
      spirits.sort(function(a, b) {return a.order - b.order;});
   }
   
   this.removeFrom = function(spirits) {
      spirits.remove(this);
   }
}

function Circle(x, y) {
   Spirit.call(this, null, x, y); // 调用父类的构造体
   
   this.radius = 1;
   this.color = 255;
   
   this.update = function(spirits) {      
      this.color -= 20;
      this.radius += 10;
      
      if (this.color <= 0) {
         this.removeFrom(spirits);
      }
   }
   
   this.draw = function(context) {
      context.beginPath();
      context.strokeStyle = "rgb("+ this.color +", "+ this.color +", "+ this.color +")";
      context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
      context.stroke();
   }
}
Circle.prototype = new Spirit(); //继承关系


window.onload = function() {
   var canvas = document.getElementById("canvas");
   canvas.width = screen.width - 30;
   canvas.height = screen.height - 100;
   var context = canvas.getContext("2d");
   
   var buffer = document.createElement("canvas");
   buffer.width = canvas.width;
   buffer.height = canvas.height;
   var bufferCtx = buffer.getContext("2d");
   
   var spirits = new Array();
   
   const FPS = 20;
   
   setInterval(draw, 1000 / FPS);
   
   document.onmousemove = function(event) {
      var circle = new Circle(event.clientX, event.clientY);
      circle.addTo(spirits);
   }
   
   function draw() {
      bufferCtx.fillRect(0, 0, buffer.width, buffer.height);
      context.fillRect(0, 0, canvas.width, canvas.height);
      
      for (x in spirits) {
         if (spirits[x].update) {
            spirits[x].update(spirits);
         }
      }
      
      for (x in spirits) {
         if (spirits[x].draw) {
            spirits[x].draw(bufferCtx);
         }
      }
      
      context.drawImage(buffer, 0, 0);
   }
}


</script>
</body>
</html>